home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / qbnws105.zip / QBFORMAT.ZIP / QBFORMAT.BAS < prev   
BASIC Source File  |  1990-10-25  |  17KB  |  525 lines

  1. DECLARE FUNCTION QBFORMAT% (drive%, media%)
  2. DECLARE FUNCTION FormatDisk% (drive%)
  3. DECLARE FUNCTION FormatTrack% (drive%, track%, head%)
  4. DECLARE FUNCTION ValidateDisk% (drive%, media%)
  5. DECLARE FUNCTION WriteBoot% (drive%)
  6. DECLARE FUNCTION WriteDir% (drive%)
  7. DECLARE FUNCTION WriteFAT% (drive%)
  8. DECLARE FUNCTION WriteSector% (drive%, cyl%, hd%, sec%)
  9. DECLARE FUNCTION WriteBootSector% (drive%)
  10. DECLARE SUB ComputeCHS (LogSec%, cyl%, hd%, sec%)
  11. DECLARE SUB InitFormatParms (media%)
  12. DECLARE SUB ResetFDC (drive%)
  13.  
  14. 'QBFORMAT.BAS by Cornel Huth 31-Oct-90
  15. 'format MS-DOS floppy disks using QB and BIOS
  16. 'requires QB.QLB/QB.LIB (specifically INTERRUPTX())
  17.  
  18. '{5.25-inch media types supported in this code}
  19. '{DS9=double-sided 9-sector(360K)  DS15=double-sided 15-sector (1.2M)}
  20. CONST DS9 = &HFD, DS15 = &HF9
  21. '{3.5-inch media types partially supported in this code}
  22. '{DX9=double-sided 9-sector(720K)  DX18=double-sided 18-sector (1.44M)}
  23. '{*** DX9 media byte is NEGATIVE to differ from DS15 ***}
  24. CONST DX9 = -&HF9, DX18 = &HF0
  25. CONST RETRIES = 3  '{retries on BIOS error}
  26.  
  27. TYPE REGtypeX
  28. ax AS INTEGER
  29. bx AS INTEGER
  30. cx AS INTEGER
  31. dx AS INTEGER
  32. bp AS INTEGER
  33. si AS INTEGER
  34. di AS INTEGER
  35. flags AS INTEGER
  36. ds AS INTEGER
  37. es AS INTEGER
  38. END TYPE '20
  39.  
  40. TYPE ADDRFIELDtype
  41. track AS STRING * 1
  42. head AS STRING * 1
  43. sector AS STRING * 1
  44. bytesec AS STRING * 1
  45. END TYPE '4
  46.  
  47. TYPE INFOtype
  48. OEM AS STRING * 8 'system name
  49. BS AS INTEGER     'bytes/sector
  50. SC AS STRING * 1  'sectors/cluster
  51. RS AS INTEGER     'reserved sectors
  52. NF AS STRING * 1  'FATs
  53. DE AS INTEGER     'root directory entries
  54. TS AS INTEGER     'total sectors on volume
  55. MB AS STRING * 1  'media byte
  56. SF AS INTEGER     'sectors/FAT
  57. ST AS INTEGER     'sectors/track
  58. NH AS INTEGER     'heads
  59. HS AS INTEGER     'hidden sectors
  60. END TYPE '27
  61.  
  62. TYPE BOOTRECtype
  63. jmp AS STRING * 3
  64. parms AS INFOtype
  65. code AS STRING * 482
  66. END TYPE '512
  67.  
  68. '{External routine included with QB 4.0 in QB.LIB & QB.QLB}
  69. '{The INTRPT.ASM supplied with QB 4.00 has 2 known bugs, one of}
  70. '{which is so bad that this code cannot work properly with it.}
  71. '{The INTRPT.ASM supplied with QB 4.00b has 1 known bug, this}
  72. '{code will work with it but DOS BIOS INT25/26h calls will not.}
  73. '{Later versions may still have that bug!}
  74. DECLARE SUB INTERRUPTX (intnum%, ireg AS REGtypeX, oreg AS REGtypeX)
  75.  
  76. DEFINT A-Z
  77. '{INT 1Eh disk parameter table vectors}
  78. DIM SHARED OldDPTseg, OldDPToff
  79. DIM SHARED NewDPTseg, NewDPToff
  80. '{Number of tracks on media}
  81. DIM SHARED NoTracks
  82. '{format info for media}
  83. DIM SHARED Info AS INFOtype
  84. '{interface with INTERRUPTX routine}
  85. DIM SHARED ireg AS REGtypeX, oreg AS REGtypeX
  86. '{boot record buffer}
  87. DIM SHARED BootRec AS BOOTRECtype
  88. '{sector buffer to write FAT & root directory sectors}
  89. DIM SHARED SectorBuff AS STRING * 512
  90. REM $STATIC
  91. '{Allocate address field data to max possible sectors per track}
  92. DIM SHARED AddrField(1 TO 18) AS ADDRFIELDtype
  93.  
  94. BootSector:
  95. DATA &HEB,&H3E,&H90,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H0,&H0,&H0,&H0,&H0
  96. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  97. DATA &HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  98. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  99. DATA &H2B,&HC0,&H8E,&HD0,&HBC,&H0,&H7C,&HB8,&HC0,&H7,&H8E,&HD8,&H8E,&HC0,&HBE,&H3
  100. DATA &H0,&HBF,&HAF,&H0,&HB9,&H4,&H0,&HF3,&HA5,&HBE,&HAF,&H0,&HB4,&HE,&H8A,&H4
  101. DATA &HA,&HC0,&H74,&H7,&H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&HFC,&HBE,&H7A,&H0,&HBF
  102. DATA &H0,&H2,&HB9,&H0,&H2,&HF3,&HA4,&HE9,&H86,&H1,&HB8,&H1,&H2,&H2B,&HDB,&HB9
  103. DATA &H1,&H0,&HBA,&H50,&H0,&HCD,&H13,&H72,&HC,&HBB,&HFE,&H1,&H81,&H3F,&H55,&HAA
  104. DATA &H75,&H3,&HE9,&HE5,&HFD,&HBE,&H58,&H2,&HB4,&HE,&H8A,&H4,&HA,&HC0,&H74,&H7
  105. DATA &H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&H2B,&HC0,&HCD,&H16,&HCD,&H19,&HCD,&H18,&H20
  106. DATA &H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H6E,&H6F,&H6E,&H2D,&H62,&H6F,&H6F,&H74
  107. DATA &H61,&H62,&H6C,&H65,&H20,&H64,&H69,&H73,&H6B,&H20,&H69,&H6E,&H20,&H41,&H3A,&HD
  108. DATA &HA,&H0,&H4E,&H6F,&H20,&H62,&H6F,&H6F,&H74,&H20,&H64,&H69,&H73,&H6B,&H20,&H66
  109. DATA &H6F,&H75,&H6E,&H64,&H2C,&H20,&H72,&H65,&H70,&H6C,&H61,&H63,&H65,&H20,&H61,&H6E
  110. DATA &H64,&H20,&H70,&H72,&H65,&H73,&H73,&H20,&H61,&H20,&H6B,&H65,&H79,&H20,&HD,&HA
  111. DATA &HD,&HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  112. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  113. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  114. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  115. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  116. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  117. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  118. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  119. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  120. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  121. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  122. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  123. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  124. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  125. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  126. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H55,&HAA
  127.  
  128. '============================================================================
  129. '{The following code is a sample run to format a disk}
  130. '{All other code can be compiled and put in a library}
  131. '{format test drive A: double-sided/9-sector media (360K)}
  132. '{...and you thought that this was going to be hard}
  133. drive = 0: media = DS9
  134. CLS : DO: LOOP WHILE INKEY$ <> ""
  135. INPUT "Insert DS9 disk to format in drive A: and press a key", a$
  136. INPUT "Press a key to start QBFORMAT", a$
  137. PRINT "formatting..."
  138. xerr = QBFORMAT(drive, media)
  139. IF xerr THEN
  140.    errl = xerr \ 256
  141.    errc = xerr AND 255
  142.    PRINT "*** Error level:"; errl; " code:"; errc
  143. ELSE
  144.    PRINT "done."
  145. END IF
  146. STOP
  147.  
  148. SUB ComputeCHS (LogSec, cyl, hd, sec)
  149. '{convert a DOS logical sector to BIOS form}
  150. CylSec = Info.ST * Info.NH
  151. cyl = LogSec \ CylSec
  152. rm = LogSec - (cyl * CylSec)
  153. hd = rm \ Info.ST
  154. sec = rm - (hd * Info.ST) + 1
  155.  
  156. END SUB
  157.  
  158. FUNCTION FormatDisk (drive)
  159. '{format a track at a time a side at a time}
  160. '{any error aborts format,diskette presumed unreliable}
  161. '{retry format 1 or 2 more times before trashing the diskette}
  162. FOR track = 0 TO (NoTracks - 1)
  163.    FOR head = 0 TO (Info.NH - 1)
  164.       FOR i = 1 TO RETRIES
  165.          xerr = FormatTrack(drive, track, head)
  166.          IF xerr = 0 THEN EXIT FOR
  167.       NEXT
  168.       IF xerr THEN FormatDisk = xerr: EXIT FUNCTION
  169.    NEXT
  170. NEXT
  171. FormatDisk = 0
  172.  
  173. END FUNCTION
  174.  
  175. FUNCTION FormatTrack (drive, track, head)
  176. '{Initialize address field for each sector on this track}
  177. FOR sec = 1 TO Info.ST
  178.    AddrField(sec).track = CHR$(track)
  179.    AddrField(sec).head = CHR$(head)
  180.    AddrField(sec).sector = CHR$(sec)
  181.    AddrField(sec).bytesec = CHR$(2)  '{bytecode 2 = 512-byte sector}
  182. NEXT
  183. ireg.ax = &H500 + Info.ST            '{format track with sectors/track}
  184. ireg.cx = (track * 256) + 1          '{track to format,start with sector 1}
  185. ireg.dx = (head * 256) + drive       '{head,drive}
  186. ireg.es = VARSEG(AddrField(1))       '{point to address field data}
  187. ireg.bx = VARPTR(AddrField(1))
  188. INTERRUPTX &H13, ireg, oreg
  189. cf = oreg.flags AND 1                '{cf=1 if disk error}
  190. IF cf THEN
  191.    e& = oreg.ax
  192.    IF e& < 0 THEN e& = e& + 65536
  193.    FormatTrack = e& \ 256            '{return with status byte}
  194.    ResetFDC drive
  195. ELSE ireg.ax = &H400 + Info.ST       '{ok, verify track integrity-}
  196.    INTERRUPTX &H13, ireg, oreg       '{-optional but recommended on format}
  197.    cf = oreg.flags AND 1             '{cf=1 if disk error}
  198.    IF cf THEN
  199.       e& = oreg.ax
  200.       IF e& < 0 THEN e& = e& + 65536
  201.       FormatTrack = e& \ 256         '{return with status byte}
  202.       ResetFDC drive
  203.    ELSE
  204.       FormatTrack = 0                '{format ok}
  205.    END IF
  206. END IF
  207.  
  208. END FUNCTION
  209.  
  210. SUB InitFormatParms (media)
  211. '{set up media's format data}
  212. Info.OEM = "IBM  3.1"   '{avoid chan